#ifndef OCEAN_VAGSDK_VAGSDK_UTIL_H
#define OCEAN_VAGSDK_VAGSDK_UTIL_H

#include <jni.h>
#include "dauproxy.h"
#include "jni_util.h"

#define THROW_VAG_EX(env, msg)          \
    do {                                \
        (env)->ThrowNew((JNIHandle::GetInstance()->cls_vagApi_ex), (msg));     \
    } while(0)

#define CHECK_CODE_THROW_VAG_EX(env, code, msg) \
    do {                                        \
        if ((code) < 0) {                       \
           THROW_VAG_EX(env, msg);                                     \
        }           \
    } while(0)

#define CHECK_NULL_RETURN_THROW_API_EX(env, x, msg, rs)    \
    do {                                                       \
        if ((x) == nullptr) {                                  \
            THROW_VAG_EX(env, msg);              \
            return (rs);                                         \
        }                                                      \
    } while(0)

#define CHECK_NULL_RETURN_THROW_API_EX_AND_DELETE_REF(env, x, msg, rs, jobj)    \
    do {                                                       \
        if ((x) == nullptr) {                                               \
            (env)->DeleteLocalRef((jobj));         \
            THROW_VAG_EX(env, msg);              \
            return (rs);                                         \
        }                                                      \
    } while(0)

#define CHECK_NULL_RETURN_THROW_API_EX_AND_DELETE_REF2(env, x, msg, rs, jobj1, jobj2)    \
    do {                                                       \
        if ((x) == nullptr) {                                               \
            (env)->DeleteLocalRef((jobj1));                                              \
            (env)->DeleteLocalRef((jobj2));                            \
            THROW_VAG_EX(env, msg);              \
            return (rs);                                         \
        }                                                      \
    } while(0)

#define CHECK_NULL_RETURN_THROW_API_EX_AND_DELETE_REF3(env, x, msg, rs, jobj1, jobj2, jobj3)    \
    do {                                                       \
        if ((x) == nullptr) {                                               \
            (env)->DeleteLocalRef((jobj1));                                              \
            (env)->DeleteLocalRef((jobj2));                                                     \
            (env)->DeleteLocalRef((jobj3));                 \
            THROW_VAG_EX(env, msg);              \
            return (rs);                                         \
        }                                                      \
    } while(0)

#define RETURN_V_IF_FALSE(rs, returnValue)    \
    do{                          \
         if (!((rs).isSuccess)) {   \
            return (returnValue);   \
         }                      \
    } while(0)

#define RETURN_IF_FALSE(rs)    \
    do{                          \
         if (!((rs).isSuccess)) {   \
            return; \
         }                      \
    } while(0)


struct ParseDeviceInfoRs {
    _proxy_dev_info info{};
    string uuid;
    bool isSuccess = false;
};

ParseDeviceInfoRs ParseDeviceInfo(JNIEnv *env, jobject deviceInfo, bool isCheckUuid);

struct ParseProxyShowStringInfoRs
{
    _proxy_showstring_info info{};
    bool isSuccess = false;
};

ParseProxyShowStringInfoRs ParseProxyShowStringInfo(JNIEnv *env, jobject showString);

struct ParseAlarmInfoRs
{
    _setup_alarm_info info{};
    bool isSuccess = false;
};

ParseAlarmInfoRs ParseSetupAlarmInfo(JNIEnv *env, jobject setupAlarm);

// Type for DauDeviceInfo
typedef _jobject *jDauDeviceInfo;
jDauDeviceInfo ConvertFromDauDeviceInfo(JNIEnv *env, _dau_device_info dauInfo);

typedef _jobject *jDevChannelInfo;
jDevChannelInfo ConvertFromDevChannelInfo(JNIEnv *env, _device_channel_info channelInfo);

typedef _jobject *jShowStringInfo;
jShowStringInfo ConvertFromProxyShowStringInfo(JNIEnv *env, _proxy_showstring_info ssi);

#endif //OCEAN_VAGSDK_VAGSDK_UTIL_H
